﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Windows_Azure_App.DataModel
{
    static class HTMLtoRTFHelper
    {
        public static string HTMLtoRTF(string sHTML)
        {
            string[] ColorTable = new string[0];
            string[] FontTable = new string[0];
            string htmltortf = "";
            int FontNumber = 0, ColorCombNumber = 0;
            int lStart = 0, lEnd = 0, lTStart = 0, lTEnd = 0;
            bool bFound = false, bFaceFound = false;
            string sFontTable = "", sColorTable = "";
            string PreviousFontFace = "", DefaultFace = ""; int PreviousFontSize = 0;
            string sHead = "", sRTF = "", sText = "";
            int lLen = 0, lCurrentToken = 0;
            string sToken = "", sTemp = "";
            int I = 0;
            bool bUseDefaultFace = false;

            //Fix the HTML 
            sHTML.Trim();
            sHTML = sHTML.Replace("<STRONG>", "<B>");
            sHTML = sHTML.Replace("</STRONG>", "</B>");
            sHTML = sHTML.Replace("<EM>", "<I>");
            sHTML = sHTML.Replace("</EM>", "</I>");
            sHTML = sHTML.Replace("\n", "");
            sHTML = sHTML.Replace("&nbsp;", "\\~");
            //Debug.WriteLine("siva " + sHTML); 
            //Initialize 
            lLen = sHTML.Length;
            lStart = 1;
            lEnd = 1;
            //Add some default fonts 
            Array.Resize(ref FontTable, 2);
            FontTable[0] = "Times New Roman";
            FontNumber = FontNumber + 1;
            FontTable[1] = "MS Sans Serif";
            FontNumber = FontNumber + 1;
            PreviousFontSize = 24; //12 default font size 
            //Add some default color 
            Array.Resize(ref ColorTable, 4);
            ColorTable[0] = "000000";
            //Black 
            ColorCombNumber = ColorCombNumber + 1;
            ColorTable[1] = "ff0000";
            //Red 
            ColorCombNumber = ColorCombNumber + 1;
            ColorTable[2] = "00ff00";
            //Green 
            ColorCombNumber = ColorCombNumber + 1;
            ColorTable[3] = "0000ff";
            //Blue 
            ColorCombNumber = ColorCombNumber + 1;
            //Parse the HTML 
            for (lCurrentToken = 1; lCurrentToken < lLen; lCurrentToken++)
            {
                lStart = sHTML.IndexOf("<", lEnd);
                if (lStart < 0)
                    goto Completed;
                lEnd = sHTML.IndexOf(">", lStart);
                sToken = sHTML.Substring(lStart, lEnd - lStart + 1).ToUpper();
                //Debug.WriteLine("string  :" + sToken); 
                //Take action 
                switch (sToken)
                {
                    case "<B>":
                        sRTF = sRTF + "\\b1";
                        break;
                    case "</B>":
                        sRTF = sRTF + "\\b0";
                        break;
                    case "<I>":
                        sRTF = sRTF + "\\i1";
                        break;
                    case "</I>":
                        sRTF = sRTF + "\\i0";
                        break;
                    case "<U>":
                        sRTF = sRTF + "\\ul1";
                        break;
                    case "</U>":
                        sRTF = sRTF + "\\ul0";
                        break;
                    case "<TR>":
                        sRTF = sRTF + "\\intbl";
                        break;
                    case "</TR>":
                        sRTF = sRTF + "\\row";
                        break;
                    case "<TD>":
                    case "</TD>":
                        sRTF = sRTF + "\\cell ";
                        break;
                    case "<BR/>":
                    case "</P>":
                        sRTF = sRTF + "\n" + "\\par ";
                        break;
                    case "</SPAN>":
                        bUseDefaultFace = true;
                        sRTF = sRTF + "\\plain\\cf1";
                        break;
                    default:
                        //if (sToken.Substring(0, 6).ToUpper() == "<TABLE") 
                        //{ 
                        sRTF = sRTF + "\\plain";
                        //sRTF = sRTF + GetTableStructure(sHTML, lStart); 
                        // } 
                        break;
                }

                //Set font and color table 
                //Check for fonts 
                if (sToken.IndexOf("SPAN", 1) > 0 && sToken.Substring(1, 1) != "/")
                {
                    Debug.WriteLine("span: " + sToken);
                    bUseDefaultFace = false;
                    lTStart = sToken.IndexOf("FONT-FAMILY: ", 1);
                    //Debug.WriteLine("lTStart: " + lTStart); 
                    if (lTStart > 0)
                    {
                        bFaceFound = true;
                        lTEnd = sToken.IndexOf("\\\"\\\"", lTStart + ("FONT-FAMILY: ").Length + 1);
                        if (lTEnd < 0)
                        {
                            lTEnd = sToken.IndexOf(" ", lTStart + ("FONT-FAMILY: ").Length);
                        }
                        if (lTEnd < 0)
                        {
                            lTEnd = sToken.IndexOf(">", lTStart + ("FONT-FAMILY: ").Length);
                        }
                        //Debug.WriteLine("lTEnd: " + lTEnd); 
                        sTemp = sToken.Substring(lTStart + ("FONT-FAMILY: ").Length, lTEnd - (lTStart + ("FONT-FAMILY: ").Length));
                        //Debug.WriteLine("Font: " + sTemp); 
                        sTemp = sTemp.Replace("\\\"\\\"", "");
                        if (sTemp != "")
                        {
                            bFaceFound = true;
                            //Check if it is already in the table 
                            if (FontTable.Length != 0)
                            {
                                for (I = 0; I < FontTable.Length; I++)
                                {
                                    if (sTemp == FontTable[I])
                                    {
                                        bFound = true;
                                        break;
                                    }
                                }
                            }
                            else
                                bFound = false;
                        }
                        //If not found add it 
                        if (bFound == false)
                        {
                            Array.Resize(ref FontTable, FontNumber + 1);
                            FontTable[FontNumber] = sTemp;
                            FontNumber = FontNumber + 1;
                            PreviousFontFace = sTemp;
                            if (DefaultFace == "")
                                DefaultFace = sTemp;
                        }
                        sRTF = sRTF + "\\f" + GetIndex(FontTable, sTemp);
                        sTemp = "";
                        bFound = false;
                    }
                    else
                        bFaceFound = false;
                }
                lTStart = sToken.IndexOf("FONT-SIZE: ", 1);

                if (lTStart > 0)
                {
                    lTEnd = sToken.IndexOf(" ", lTStart + ("FONT-SIZE: ").Length);
                    if (lTEnd == 0)
                    {
                        lTEnd = sToken.IndexOf(">", lTStart + ("FONT-SIZE: ").Length);
                    }
                    sTemp = sToken.Substring(lTStart + ("FONT-SIZE: ").Length, lTEnd - (lTStart + ("FONT-SIZE: ").Length)).Replace("\\\"\\\"", "");
                    if (sTemp != "")
                    {
                        sTemp = GetFontSize(sTemp);
                        if (Convert.ToInt64(sTemp) < 0)
                            sTemp = Convert.ToString(PreviousFontSize);
                        PreviousFontSize = Convert.ToInt32(sTemp);
                        //Debug.WriteLine("size: " + PreviousFontSize); 
                        sTemp = "";
                    }
                    bFound = false;
                }
                //Check for colors 
                lTStart = sToken.IndexOf("COLOR: ", 1);
                if (lTStart > 0)
                {
                    lTEnd = sToken.IndexOf(" ", lTStart + ("COLOR: ").Length);
                    if (lTEnd == 0)
                    {
                        lTEnd = sToken.IndexOf(">", lTStart + ("COLOR: ").Length);
                    }
                    sTemp = sToken.Substring(lTStart + ("COLOR: ").Length, lTEnd - (lTStart + ("COLOR: ").Length));
                    sTemp = sTemp.Replace("\\\"\\\"", "");
                    sTemp = sTemp.Replace("#", "");
                    //Debug.WriteLine("color: " + sTemp); 
                    if (sTemp != "")
                    {
                        //Check if it is already in the table 
                        if (ColorTable.Length != 0)
                        {
                            for (I = 0; I < ColorTable.Length; I++)
                            {
                                if (sTemp == ColorTable[I])
                                {
                                    bFound = true;
                                    break;
                                }
                            }
                        }
                        else
                            bFound = false;
                    }
                    //If not found add it 
                    if (bFound == false)
                    {
                        Array.Resize(ref  ColorTable, ColorCombNumber + 1);
                        ColorTable[ColorCombNumber] = sTemp;
                        ColorCombNumber = ColorCombNumber + 1;
                    }
                    int c = GetIndex(ColorTable, sTemp);
                    c = c + 1;
                    Debug.WriteLine("Color: " + c);
                    sRTF = sRTF + "\\cf" + c;
                    sTemp = "";
                    bFound = false;
                }
                //Debug.WriteLine("Color: " + sRTF); 

                //Get the text 
                lStart = sHTML.IndexOf(">", lEnd);
                //Debug.WriteLine("lStart: " + lStart); 
                if (lStart < 0)
                    goto Completed;
                lEnd = sHTML.IndexOf("<", lStart);
                //Debug.WriteLine("lEnd: " + lEnd); 
                if (lEnd < 0)
                    goto Completed;
                sText = sHTML.Substring(lStart, (lEnd - lStart) + 1);
                sText = sText.Trim();
                sText = sText.Replace("<", "");
                sText = sText.Replace(">", "");
                if ((sText).Length > 2 && sText != "")
                {
                    sText = sText.Substring(0, (sText).Length);
                    //check out for special characters 
                    sText = sText.Replace("\\", "\\\\");
                    sText = sText.Replace("{", "\\{");
                    sText = sText.Replace("}", "\\}");
                    if (bFaceFound = false && bUseDefaultFace)
                    {
                        sTemp = Convert.ToString(GetIndex(FontTable, DefaultFace)); //PreviousFontFace) 
                        if (Convert.ToInt32(sTemp) < 0)
                            sRTF = sRTF + "\\f0";
                        else
                            sRTF = sRTF + "\\f" + sTemp;
                        sTemp = "";
                    }
                    sRTF = sRTF + "\\fs" + PreviousFontSize * 2 + " " + sText;
                }
                //Debug.WriteLine("sText: " + sRTF); 
            }
        Completed:
            //Generate Font Table 
            sFontTable = "\\deff0{\\fonttbl";
            if (FontTable.Length != 0)
            {
                for (I = 0; I < FontTable.Length; I++)
                    sFontTable = sFontTable + "{\\f" + I + "\\fnil\\fcharset0 " + FontTable[I] + ";}";
                sFontTable = sFontTable + "}";
            }
            else
            {
                sFontTable = sFontTable + "{\\f0\\froman\\fcharset0 Times New Roman;}}";
                Array.Resize(ref FontTable, 0);
                FontTable[0] = "Times New Roman";
                //FontTable(0).SIZE = "18" 
            }

            //Generate Color Table 
            sColorTable = "{\\colortbl;";
            if (ColorTable.Length != 0)
            {
                for (I = 0; I < ColorTable.Length; I++)
                {
                    //Debug.WriteLine("Color: "+ColorTable[I]); 
                    sColorTable = sColorTable + "\\red" + GetRed(ColorTable[I]) + "\\green" + GetGreen(ColorTable[I]) + "\\blue" + GetBlue(ColorTable[I]) + ";";
                }
                sColorTable = sColorTable + "}";
            }
            else
            {
            }
            //Generate head 
            sHead = "{\\rtf1\\ansi" + sFontTable + "\n" + sColorTable;
            sHead = sHead + "\n" + "\\pard\\plain\\tx0";

            htmltortf = sHead + sRTF + "}";
            //Debug.WriteLine("htmltortf: " + htmltortf); 
            return htmltortf;
        }
        static int GetRed(string HexString)
        {
            string sTemp = "";
            sTemp = HexString.Substring(0, 2);
            //Debug.WriteLine("" + Convert.ToInt32(sTemp,16)); 
            return Convert.ToInt32(sTemp, 16);
        }
        static int GetGreen(string HexString)
        {
            string sTemp = "";
            sTemp = HexString.Substring(2, 2);
            //Debug.WriteLine("" + Convert.ToInt32(sTemp,16)); 
            return Convert.ToInt32(sTemp, 16);
        }
        static int GetBlue(string HexString)
        {
            string sTemp = "";
            sTemp = HexString.Substring(4, 2);
            //Debug.WriteLine("" + Convert.ToInt32(sTemp,16)); 
            return Convert.ToInt32(sTemp, 16);
        }
        
        static string GetFontSize(string sTemp)
        {
            string getfontsize = "";
            try
            {
                switch (sTemp)
                {
                    case "1":
                        getfontsize = "30";//"7.5" 
                        break;
                    case "2":
                        getfontsize = "40";// '"10" 
                        break;
                    case "3":
                        getfontsize = "48";// '"12" 
                        break;
                    case "4":
                        getfontsize = "54";// '"13.5" 
                        break;
                    case "5":
                        getfontsize = "72";// '"18" 
                        break;
                    case "6":
                        getfontsize = "96";// '"24" 
                        break;
                    case "7":
                        getfontsize = "144";// '"36" 
                        break;
                    default:
                        getfontsize = Convert.ToString((Math.Round(Convert.ToDouble(sTemp))));
                        break;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("" + e);
            }
            return getfontsize;
        }
        static int GetIndex(string[] Table, string Code)
        {
            int I = 0, getindex = 0;
            bool bFound = false;
            try
            {

                //Get the index 
                if (Table.Length != 0)
                {
                    for (I = 0; I < Table.Length; I++)
                    {
                        if (Code == Table[I])
                        {
                            bFound = true;
                            break;
                        }
                    }
                }
                else
                    bFound = false;

                //return it 
                if (bFound == false)
                    getindex = 0;
                else
                    getindex = I;

            }
            catch (Exception e)
            {
                Debug.WriteLine("" + e);
            }
            return getindex;
        }
    }
}
